package com.jmda.platform.repository.generator.action;

import com.jmda.platform.commom.LocalCacheManager;
import com.jmda.platform.commom.SpringContextUtil;
import com.jmda.platform.commom.util.FileUtil;
import com.jmda.platform.repository.ResositoryException;
import com.jmda.platform.repository.application.model.ApplicationModel;
import com.jmda.platform.repository.application.service.ApplicationSevice;
import com.jmda.platform.repository.form.model.FormModel;
import com.jmda.platform.repository.form.service.FormMetadataService;
import com.jmda.platform.repository.form.service.FormService;
import com.jmda.platform.repository.generator.model.GeneratorModel;
import com.jmda.platform.repository.generator.model.GeneratorTablePo;
import com.jmda.platform.repository.metadata.model.MetadataModel;
import com.jmda.platform.repository.metadata.service.MetadataService;
import com.jmda.platform.repository.worklist.model.ColumnModel;
import com.jmda.platform.repository.worklist.model.WorkListModel;
import com.jmda.platform.repository.worklist.service.WorkListService;
import freemarker.core.ParseException;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping("/repository/generator")
public class GeneratorController {
	@Resource
	ApplicationSevice applicationSevice;
	@Resource
	MetadataService metadataService;
	@Resource
	WorkListService workListService;
	@Resource
	FormService formService;
	@Resource
	FormMetadataService formMetadataService;
	@RequestMapping(method = { RequestMethod.POST, RequestMethod.GET })
	public String getGeneratorPage(String applicationId, ModelMap map) throws ResositoryException {
		ApplicationModel appModel = applicationSevice.get(applicationId);
		String webBasePath = LocalCacheManager.jmdaPropertiesMap.get("system.src.web.basePath");
		String serviceBasePath = LocalCacheManager.jmdaPropertiesMap.get("system.src.service.basePath");
		String javaBasePackage = LocalCacheManager.jmdaPropertiesMap.get("system.java.basePackage");
		List<MetadataModel> listMeatadata = metadataService.getAll();
		List<GeneratorTablePo> tableList = new ArrayList<GeneratorTablePo>();
		for (MetadataModel model : listMeatadata) {
			GeneratorTablePo generatorTablePo = new GeneratorTablePo();
			generatorTablePo.setClassName(StringUtils.capitalize(camelName(model.getTABLE_NAME())));
			generatorTablePo.setTableName(model.getTABLE_NAME());
			tableList.add(generatorTablePo);
		}
		Collections.sort(tableList, new Comparator<GeneratorTablePo>() {
			public int compare(GeneratorTablePo arg0, GeneratorTablePo arg1) {
				return arg0.getTableName().compareTo(arg1.getTableName());
			}
		});
		FormModel paramsFormModel = new FormModel();
		paramsFormModel.setApplication_id(applicationId);

		WorkListModel worklistParams = new WorkListModel();
		worklistParams.setApplicationId(applicationId);

		map.put("tableList", tableList);
		map.put("worklistList", workListService.queryList(worklistParams));
		map.put("formList", formService.queryList(paramsFormModel));
		map.put("webBasePath", webBasePath);
		map.put("serviceBasePath", serviceBasePath);
		map.put("javaBasePackage", javaBasePackage);
		map.put("applicationId", appModel.getXieyin_code());
		return "repository/generator/Sys_Repository_Generator";
	}

	@RequestMapping(value = "/execute", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public String execute(GeneratorModel model) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException, ResositoryException {
		String webBasePath = LocalCacheManager.jmdaPropertiesMap.get("system.src.web.basePath");
		String javaBasePackage = LocalCacheManager.jmdaPropertiesMap.get("system.java.basePackage");
		String serviceBasePath = LocalCacheManager.jmdaPropertiesMap.get("system.src.service.basePath");
		StringBuffer msg = new StringBuffer();
		// TODO 生成 java controller 代码
		if (model.getJavaController().trim().length() > 0) {
			String folderPath = webBasePath + "/src/main/java/" + javaBasePackage + "/" + model.getApplicationId() + "/controller/";
			folderPath = folderPath.replaceAll("\\\\", "/").replaceAll("\\.", "/");
			File folderFile = new File(folderPath);
			if (!folderFile.exists()) {
				folderFile.mkdirs();
			}
			String filePath = folderPath + model.getJavaClass() + "Controller.java";
			File file = new File(filePath);
			if (file.exists()) {
				msg.append("JAVA Controller 代码生成失败，已经存在文件[" + filePath + "]</br>");
			} else {
				Map<String, Object> templeteMap = new HashMap<String, Object>();
				FreeMarkerConfigurer freeMarkerConfigurer = SpringContextUtil.getBean("freemarkerConfig");
				Template template = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_genenator_java_controller.ftl");
				templeteMap.put("model", model);
				templeteMap.put("project_path", LocalCacheManager.jmdaPropertiesMap.get("system.java.basePackage"));
				templeteMap.put("request_mapper", model.getApplicationId().replaceAll("\\.", "/"));
				String javaControllerStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, templeteMap);
				FileUtil.write(filePath, javaControllerStr);
			}
		}

		// TODO 生成java service 代码
		if (model.getJavaService().trim().length() > 0) {
			String folderPath = serviceBasePath + "/src/main/java/" + javaBasePackage + "/" + model.getApplicationId() + "/service/";
			folderPath = folderPath.replaceAll("\\\\", "/").replaceAll("\\.", "/");
			File folderFile = new File(folderPath);
			if (!folderFile.exists()) {
				folderFile.mkdirs();
			}
			String filePath = folderPath + model.getJavaClass() + "Service.java";
			File file = new File(filePath);
			if (file.exists()) {
				msg.append("JAVA Service 代码生成失败，已经存在文件[" + filePath + "]</br>");
			} else {
				Map<String, Object> templeteMap = new HashMap<String, Object>();
				FreeMarkerConfigurer freeMarkerConfigurer = SpringContextUtil.getBean("freemarkerConfig");
				Template template = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_genenator_java_service.ftl");
				templeteMap.put("model", model);
				templeteMap.put("project_path", LocalCacheManager.jmdaPropertiesMap.get("system.java.basePackage"));
				String javaControllerStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, templeteMap);
				FileUtil.write(filePath, javaControllerStr);
			}
		}
		// TODO 生成java serviveImp 代码
		if (model.getJavaService().trim().length() > 0) {
			String folderPath = serviceBasePath + "/src/main/java/" + javaBasePackage + "/" + model.getApplicationId() + "/service/imp/";
			folderPath = folderPath.replaceAll("\\\\", "/").replaceAll("\\.", "/");
			File folderFile = new File(folderPath);
			if (!folderFile.exists()) {
				folderFile.mkdirs();
			}
			String filePath = folderPath + model.getJavaClass() + "ServiceImp.java";
			File file = new File(filePath);
			if (file.exists()) {
				msg.append("JAVA Service imp 代码生成失败，已经存在文件[" + filePath + "]</br>");
			} else {
				Map<String, Object> templeteMap = new HashMap<String, Object>();
				FreeMarkerConfigurer freeMarkerConfigurer = SpringContextUtil.getBean("freemarkerConfig");
				Template template = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_genenator_java_service_imp.ftl");
				templeteMap.put("model", model);
				templeteMap.put("project_path", LocalCacheManager.jmdaPropertiesMap.get("system.java.basePackage"));
				String javaControllerStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, templeteMap);
				FileUtil.write(filePath, javaControllerStr);
			}
		}

		// TODO 自动生成FormJS代码
		if (model.getFormJs().trim().length() > 0) {
			FormModel formModel = formService.get(model.getFormId());
			if (formModel != null && formModel.getXieyin_code() != null && formModel.getXieyin_code().trim().length() > 0) {
				String folderPath = webBasePath + "/src/main/webapp/static/js/" + model.getApplicationId();
				folderPath = folderPath.replaceAll("\\\\", "/").replaceAll("\\.", "/");
				File folderFile = new File(folderPath);
				if (!folderFile.exists()) {
					folderFile.mkdirs();
				}
				String filePath = folderPath +  "/"+formModel.getXieyin_code()+"_form.js";
				File file = new File(filePath);
				if (file.exists()) {
					msg.append("JS form 代码生成失败，已经存在文件[" + filePath + "]</br>");
				} else {
					Map<String, Object> templeteMap = new HashMap<String, Object>();
					FreeMarkerConfigurer freeMarkerConfigurer = SpringContextUtil.getBean("freemarkerConfig");
					Template template = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_genenator_js_form.ftl");
					templeteMap.put("model", model);
					templeteMap.put("request_mapper", model.getApplicationId().replaceAll("\\.", "/"));
					templeteMap.put("formMetadataList", formMetadataService.getSubFormMetadataList(model.getFormId()));
					String javaControllerStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, templeteMap);
					FileUtil.write(filePath, javaControllerStr);
					formModel.setExtendJavascript("<script type=\"text/javascript\" src=\"${basePath}"+model.getFormJs()+"\"></script>");
					formService.store(formModel);
				}
			}
		}
		
		//TODO 自动生成 数据表格 worklistJS代码
		if(model.getWorklistJs().trim().length()>0){
			WorkListModel worklistModel=workListService.get(model.getWorklistId());
			if(worklistModel!=null&&worklistModel.getXieyin_code()!=null&&worklistModel.getXieyin_code().trim().length()>0){
				String folderPath = webBasePath + "/src/main/webapp/static/js/" + model.getApplicationId();
				folderPath = folderPath.replaceAll("\\\\", "/").replaceAll("\\.", "/");
				File folderFile = new File(folderPath);
				if (!folderFile.exists()) {
					folderFile.mkdirs();
				}
				String filePath = folderPath +  "/"+worklistModel.getXieyin_code()+"_worklist.js";
				File file = new File(filePath);
				if (file.exists()) {
					msg.append("JS worklist 代码生成失败，已经存在文件[" + filePath + "]</br>");
				} else {
					
					Map<String, Object> templeteMap = new HashMap<String, Object>();
					FreeMarkerConfigurer freeMarkerConfigurer = SpringContextUtil.getBean("freemarkerConfig");
					Template template = freeMarkerConfigurer.getConfiguration().getTemplate("system/sys_genenator_js_worklist.ftl");
					templeteMap.put("model", model);
					templeteMap.put("request_mapper", model.getApplicationId().replaceAll("\\.", "/"));
					ColumnModel pkColumn=workListService.getColumnModelPK(model.getWorklistId());
					if(pkColumn!=null){
						templeteMap.put("PK", pkColumn.getColumnName());
					}else{
						templeteMap.put("PK", "TABLE_ID");
					}
					String javaControllerStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, templeteMap);
					FileUtil.write(filePath, javaControllerStr);
					worklistModel.setExtendJavascript("<script type=\"text/javascript\" src=\"${basePath}"+model.getWorklistJs()+"\"></script>");
					workListService.store(worklistModel);
				}
			}
		}

		return msg.toString().trim().length()==0?"ok": msg.toString();
	}

	public String camelName(String name) {
		StringBuilder result = new StringBuilder();
		// 快速检查
		if (name == null || name.isEmpty()) {
			// 没必要转换
			return "";
		} else if (!name.contains("_")) {
			// 不含下划线，仅将首字母小写
			return name.substring(0, 1).toLowerCase() + name.substring(1);
		}
		// 用下划线将原始字符串分割
		String camels[] = name.split("_");
		for (String camel : camels) {
			// 跳过原始字符串中开头、结尾的下换线或双重下划线
			if (camel.isEmpty()) {
				continue;
			}
			// 处理真正的驼峰片段
			if (result.length() == 0) {
				// 第一个驼峰片段，全部字母都小写
				result.append(camel.toLowerCase());
			} else {
				// 其他的驼峰片段，首字母大写
				result.append(camel.substring(0, 1).toUpperCase());
				result.append(camel.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}
}
